/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Vue;

import Controleur.cliqueSouris;
import Modele.Environnement;
import Modele.Regle;
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EtchedBorder;
import javax.swing.border.SoftBevelBorder;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Classe permettant de créer une instance du jeu de la vie
 * @author FERRIER/NONGLATON
 */
public class Fenetre extends JFrame {

    private JScrollPane monConteneur;
    private JPanel maGrille;
    private JPanel conteneurBouton;
    private Case[][] mesCases;
    private Environnement myEnv;
    private JMenuBar maBarreDeMenu;
    private JButton monBoutonStart;
    private JButton monBoutonRandom;
    private JButton monBoutonClear;
    private Thread threadCalcul;
    private int hauteur;
    private int largeur;
    private Boolean etatSauvegarde;
    private File fichierSauvegarde;
    private JPanel couleurVie;
    private JPanel couleurMort;
    private JLabel lblZoom;
    private JSlider slideZoom;
    private JLabel lblVitesse;
    private JSlider slideVitesse;

    /**
     * Créé une fenêtre de jeu de base de taille 50x50 
     */
    public Fenetre() {
        this(50, 50);
    }

    /**
     * Créé une fenêtre de jeu 
     * @param h hauteur de la nouvelle grille
     * @param l largeur de la nouvelle grille
     */
    public Fenetre(int h, int l) {
        super();

        hauteur = h;
        largeur = l;
        etatSauvegarde = true;
        fichierSauvegarde = null;
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent arg0) {

                if (verifSauvegarde()) {
                    super.windowClosing(arg0);
                    setVisible(false);
                    System.exit(0);
                }

            }
        });

        setTitle("Jeu de la vie");
        //setSize(700, 730);
        this.setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

        try {
            UIManager.setLookAndFeel(new WindowsLookAndFeel());
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
        }

        conteneurBouton = new JPanel();
        conteneurBouton.setBorder(new EtchedBorder(EtchedBorder.LOWERED));

        /****
         * Initialisation Bouton Start
         */
        monBoutonStart = new JButton("Start");
        threadCalcul = new Thread();
        monBoutonStart.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (!threadCalcul.isAlive()) {
                    startThreadCalcul();
                } else {
                    stopThreadCalcul();
                }
            }
        });

        monBoutonStart.setSize(60, 30);
        monBoutonStart.setAlignmentX(CENTER_ALIGNMENT);

        conteneurBouton.add(monBoutonStart);


        /****
         * Initialisation Bouton Random
         */
        monBoutonRandom = new JButton("Random");
        monBoutonRandom.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                myEnv.generationAleatoire();
            }
        });
        monBoutonRandom.setSize(60, 30);
        monBoutonRandom.setAlignmentX(CENTER_ALIGNMENT);

        conteneurBouton.add(monBoutonRandom);

        /****
         * Initialisation Bouton Clear
         */
        monBoutonClear = new JButton("Clear");
        monBoutonClear.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                myEnv.Clear();
                stopThreadCalcul();
            }
        });

        monBoutonClear.setSize(60, 30);
        monBoutonClear.setAlignmentX(CENTER_ALIGNMENT);

        conteneurBouton.add(monBoutonClear);

        /****
         * Initialisation Choix des couleurs
         */
        couleurMort = new JPanel();
        couleurMort.setBackground(Color.white);
        couleurMort.setMinimumSize(new Dimension(15, 15));
        couleurMort.setMaximumSize(new Dimension(15, 15));
        couleurMort.setPreferredSize(new Dimension(15, 15));
        couleurMort.setAlignmentX(CENTER_ALIGNMENT);
        couleurMort.setBorder(new SoftBevelBorder(SoftBevelBorder.RAISED));
        couleurMort.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                changeCouleurMort();
            }
        });

        conteneurBouton.add(couleurMort);

        couleurVie = new JPanel();
        couleurVie.setBackground(Color.BLACK);
        couleurVie.setMinimumSize(new Dimension(15, 15));
        couleurVie.setMaximumSize(new Dimension(15, 15));
        couleurVie.setPreferredSize(new Dimension(15, 15));
        couleurVie.setAlignmentX(CENTER_ALIGNMENT);
        couleurVie.setBorder(new SoftBevelBorder(SoftBevelBorder.RAISED));
        couleurVie.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                changeCouleurVie();
            }
        });

        conteneurBouton.add(couleurVie);

        /****
         * Initialisation Slider Zoom
         */
        lblZoom = new JLabel("   Zoom:");
        slideZoom = new JSlider(4, 32, 12);

        Dimension dimensionSlide = new Dimension(60, 30);
        slideZoom.setSize(dimensionSlide);
        slideZoom.setMinimumSize(dimensionSlide);
        slideZoom.setMaximumSize(dimensionSlide);
        slideZoom.setPreferredSize(dimensionSlide);

        slideZoom.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseReleased(MouseEvent e) {
                changeZoom(slideZoom.getValue());
            }
        });

        conteneurBouton.add(lblZoom);
        conteneurBouton.add(slideZoom);


        /****
         * Initialisation Slider Vitesse
         */
        lblVitesse = new JLabel("   Vitesse:");
        slideVitesse = new JSlider(20, 1000, 300);
        slideVitesse.setSize(dimensionSlide);
        slideVitesse.setMinimumSize(dimensionSlide);
        slideVitesse.setMaximumSize(dimensionSlide);
        slideVitesse.setPreferredSize(dimensionSlide);
        conteneurBouton.add(lblVitesse);
        conteneurBouton.add(slideVitesse);


        this.add(conteneurBouton);



        /***
         * Initialisation de l'environnement
         */
        myEnv = new Environnement(largeur, hauteur);

        /***
         * Initialisation de la grille
         */
        creationGrille();

        /****
         * Initialisation Menu
         */
        maBarreDeMenu = new JMenuBar();
        JMenu menuFichier = new JMenu("Fichier");
        JMenu menuOption = new JMenu("Option");

        //Items du menu Fichier
        JMenuItem nouveau = new JMenuItem("Nouveau...");
        nouveau.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                actionNouveau();
            }
        });
        JMenuItem enregistrerSous = new JMenuItem("Enregistrer sous...");
        enregistrerSous.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                actionEnregistrerSous();
            }
        });

        JMenuItem enregistrer = new JMenuItem("Enregistrer");
        enregistrer.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                actionEnregistrer();
            }
        });

        JMenuItem charger = new JMenuItem("Charger...");
        charger.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                actionCharger();
            }
        });

        menuFichier.add(nouveau);
        menuFichier.add(enregistrer);
        menuFichier.add(enregistrerSous);
        menuFichier.add(charger);

        maBarreDeMenu.add(menuFichier);


        //Items du menu Option
        JMenuItem itemRegles = new JMenuItem("Règles...");
        itemRegles.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                actionRegles();
            }
        });
        menuOption.add(itemRegles);
        maBarreDeMenu.add(menuOption);


        this.setJMenuBar(maBarreDeMenu);

        this.pack();
        this.setMinimumSize(this.getSize());

    }

    /**
     * Créé la grille pour la fenêtre
     */
    private void creationGrille() {
        /****
         * Initialisation de l'environnement et de la grille associée
         */
        if (monConteneur != null) {
            this.remove(monConteneur);
        }

        mesCases = new Case[hauteur][largeur];
        maGrille = new JPanel();
        maGrille.setLayout(new GridLayout(hauteur, largeur));
        int tailleCase = slideZoom.getValue();
        Dimension dimensionCase = new Dimension(tailleCase, tailleCase);
        Dimension dimensionGrille = new Dimension(largeur * tailleCase, hauteur * tailleCase);
        maGrille.setSize(dimensionGrille);
        maGrille.setMaximumSize(dimensionGrille);
        maGrille.setMinimumSize(dimensionGrille);

        for (int i = 0; i < hauteur; i++) {
            for (int j = 0; j < largeur; j++) {
                Case uneCase = new Case(i, j);
                uneCase.setPreferredSize(dimensionCase);
                uneCase.setMinimumSize(dimensionCase);
                uneCase.setMaximumSize(dimensionCase);
                uneCase.setUneCellule(myEnv.getCellule(i, j));
                uneCase.addMouseListener(new cliqueSouris(this));
                mesCases[i][j] = uneCase;
                maGrille.add(uneCase);
            }
        }
        maGrille.setAlignmentX(CENTER_ALIGNMENT);
        maGrille.setAlignmentY(CENTER_ALIGNMENT);


        /****
         * Initialisation Conteneur de grille
         */
        monConteneur = new JScrollPane();
        monConteneur.setViewportView(maGrille);
        Dimension dimensionConteneur = new Dimension(300, 300);

        //Si la grille est plus petite que le conteneur il faut réduire le conteneur
        dimensionConteneur.height = dimensionConteneur.height < dimensionGrille.height ? dimensionConteneur.height : dimensionGrille.height;
        dimensionConteneur.width = dimensionConteneur.width < dimensionGrille.width ? dimensionConteneur.width : dimensionGrille.width;

        // On rajoute la taille des scrollbars au ScrollPane pour qu'elle n'empiètent pas sur le contenu
        UIDefaults uidef = UIManager.getDefaults();
        int epaisseurScrollBar = Integer.parseInt(uidef.get("ScrollBar.width").toString());

        dimensionConteneur.width += 4; //le +4 permet d'éviter d'avoir des scrollbars lorsque cela n'est pas nécessaire
        dimensionConteneur.height += 4;
        monConteneur.setPreferredSize(dimensionConteneur);
        monConteneur.setMinimumSize(dimensionConteneur);

        Dimension dimensionMax = dimensionGrille;
        dimensionMax.width += 4; //le +4 permet d'éviter d'avoir des scrollbars lorsque cela n'est pas nécessaire
        dimensionMax.height += 4;
        monConteneur.setMaximumSize(dimensionMax);
        this.add(monConteneur);

        this.setMinimumSize(null); // pour éviter que la fenetre soit bloquée dans une taille trop grande

        this.pack();
        this.repaint();
        this.setMinimumSize(this.getSize());
        conteneurBouton.setMaximumSize(new Dimension(conteneurBouton.getSize()));

    }

    /**
     * Permet de créér un planeur centré au point (x,y)
     */
    private void creerVaisseau(int x, int y) {
        myEnv.newVaisseau(x, y);
    }

    /**
     * Nouvelle grille:
     * Propose à l'utilisateur de créer une nouvelle grille de la taille qu'il souhaite
     */
    private void actionNouveau() {
        if (verifSauvegarde()) {
            DialogNouveau dialNouv = new DialogNouveau(this, true);
            dialNouv.setVisible(true);
            if (dialNouv.reussis()) {
                nouvelleGrille(dialNouv.getHauteur(), dialNouv.getLargeur());
            }
        }
    }

    /**
     * Enregistrer sous:
     * Permet de choisir un nom pour le fichier.
     * Si on choisit un fichier déjà existant une confirmation d'écrasement est demandée  
     */
    private void actionEnregistrerSous() {
        // Permet de rester dans le même fichier lors de sauvegarde multiple
        String chemin = (fichierSauvegarde == null ? System.getProperty("user.dir") : fichierSauvegarde.getParent());

        // On créé le file chooser pour des fichier d'extension .env
        JFileChooser choixFichier = new JFileChooser(chemin);
        choixFichier.setFileFilter(new FileNameExtensionFilter("Fichiers Environement", "env"));

        // On affiche le file chooser et on récupère quel bouton a été cliqué
        int retour = choixFichier.showSaveDialog(this);

        // Si l'utilisateur a choisi l'option sauvegarder
        if (retour == JFileChooser.APPROVE_OPTION) {
            boolean okEnregistrement = true;

            //Si le fichier existe déjà
            if (choixFichier.getSelectedFile().exists()) {

                // Pop-up de Confirmation
                if (JOptionPane.showOptionDialog(this,
                        "Êtes-vous sur de vouloir écraser ce fichier?",
                        "Confirmation",
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.QUESTION_MESSAGE,
                        null, null, null) == JOptionPane.NO_OPTION) {
                    // Si l'utilisateur ne veut pas écraser:
                    okEnregistrement = false;
                }
            }
            if (okEnregistrement) {
                // Si c'est ok on récupère le fichier qu'il a choisi
                fichierSauvegarde = choixFichier.getSelectedFile();
                //  et on l'enregistre
                actionEnregistrer();
            } else {
                // Sinon on repropose d'enregistrer
                actionEnregistrerSous();
            }

        }
    }

    /**
     * Enregistrement:
     * Sauvegarde la grille dans un fichier .env
     * Si un fichier est déjà ouvert on réécrit sur ce fichier sinon on propose d'enregistrer sous un nouveau nom 
     */
    private void actionEnregistrer() {
        //On arrête le thread de calcul si il a été lancé
        if (threadCalcul.isAlive()) {
            stopThreadCalcul();
        }
        if (fichierSauvegarde == null) {//si on a pas encore de chemin de sauvegarde on fait appel a enregistrerSous
            actionEnregistrerSous();
        } else {// Sinon on sauvegarde directement

            FileOutputStream fos = null;
            ObjectOutputStream oos = null;
            try {
                if (!fichierSauvegarde.getName().endsWith(".env")) {
                    fichierSauvegarde = new File(fichierSauvegarde.getPath() + ".env");
                }
                System.out.println("J'enregistre:" + fichierSauvegarde.getPath());
                fos = new FileOutputStream(fichierSauvegarde);
                oos = new ObjectOutputStream(fos);
                oos.writeObject(myEnv.versionSimplifiee());
                etatSauvegarde = true;
            } catch (FileNotFoundException ex) {
                System.out.println("Fichier non trouvé lors de l'enregistrement");
            } catch (IOException ex) {
                System.out.println("Erreur lors de l'enregistrement");
                JOptionPane.showMessageDialog(this, "Erreur durant la sauvegarde. Celle-ci n'a pu être effectuée.", "Erreur de sauvegarde", JOptionPane.ERROR_MESSAGE);
            } finally {
                // <editor-fold defaultstate="collapsed" desc="fermeture des flux">

                try {
                    if (oos != null) {
                        oos.close();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
                }
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
                }
                // </editor-fold>
            }


        }

    }

    private void actionCharger() {
        if (verifSauvegarde()) {
            // Permet de rester dans le même fichier
            String chemin = (fichierSauvegarde == null ? System.getProperty("user.dir") : fichierSauvegarde.getParent());

            // On créé le file chooser pour des fichier d'extension .env
            JFileChooser choixFichier = new JFileChooser(chemin);
            choixFichier.setFileFilter(new FileNameExtensionFilter("Fichiers Environement", "env"));

            // On affiche le file chooser et on récupère quel bouton a été cliqué
            int retour = choixFichier.showOpenDialog(this);

            // Si l'utilisateur a validé
            if (retour == JFileChooser.APPROVE_OPTION) {


                FileInputStream fis = null;
                ObjectInputStream ois = null;
                try {
                    // On récupère le fichier qu'il a choisi
                    fichierSauvegarde = choixFichier.getSelectedFile();

                    //on créé les flux nécessaire a la lecture
                    fis = new FileInputStream(fichierSauvegarde);
                    ois = new ObjectInputStream(fis);

                    // On récupère les données stockées
                    boolean[][] versionSimple;
                    versionSimple = (boolean[][]) ois.readObject();

                    nouvelleGrille(versionSimple);

                } catch (ClassNotFoundException ex) {
                    System.out.println("Problème de conversion lors de l'ouverture");
                    JOptionPane.showMessageDialog(this, "Fichier non valide. Il n'a pu être ouvert.", "Erreur d'ouverture", JOptionPane.ERROR_MESSAGE);
                } catch (StreamCorruptedException ex) {
                    System.out.println("Problème de conversion lors de l'ouverture");
                    JOptionPane.showMessageDialog(this, "Fichier non valide. Il n'a pu être ouvert.", "Erreur d'ouverture", JOptionPane.ERROR_MESSAGE);

                } catch (FileNotFoundException ex) {
                    JOptionPane.showMessageDialog(this, "Fichier non trouvé", "Erreur d'ouverture", JOptionPane.ERROR_MESSAGE);

                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(this, "Erreur lors de l'ouverture", "Erreur d'ouverture", JOptionPane.ERROR_MESSAGE);
                    System.out.println("Erreur lors de l'ouverture: " + ex.getClass());
                } finally {
                    // <editor-fold defaultstate="collapsed" desc="fermeture des flux">

                    try {
                        if (ois != null) {
                            ois.close();
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    try {
                        if (fis != null) {
                            fis.close();
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(Fenetre.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    // </editor-fold>
                }
            }
        }
    }

    private void actionRegles() {
        Regle regle = myEnv.getRegle();
        DialogNouvelleRegles nouvelleRegles = new DialogNouvelleRegles(this, true, regle.getNaissance(), regle.getSurvie());
        nouvelleRegles.setVisible(true);

        if (nouvelleRegles.isReussi()) {
            regle.setNaissance(nouvelleRegles.getNaissance());
            regle.setSurvie(nouvelleRegles.getSurvie());
        }

    }

    /**
     * Permet de vérfier la sauvegarde
     * @return - true si on a déja sauvegardé<br/>- Sinon propose la sauvegarde et tient compte de la réponse de l'utilisateur 
     */
    private boolean verifSauvegarde() {
        if (etatSauvegarde) {// Si on a déja sauvegardé
            return true;
        } else {
            int retour = JOptionPane.showConfirmDialog(this, "Voulez-vous sauvegarder la grille? (Toute donnée non sauvegardée sera perdue)", "Confirmation", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null);
            switch (retour) {
                case JOptionPane.YES_OPTION:
                    //Si l'utilisateur veut sauvegarder
                    actionEnregistrer();
                    break;
                case JOptionPane.NO_OPTION:
                    //Si l'utilisateur ne veut pas sauvegarder
                    etatSauvegarde = true;//on force l'état de sauvegarde
                    break;
            }
            return etatSauvegarde;
        }

    }

    /**
     * Créé une nouvelle grille
     * @param h hauteur de la grille
     * @param l largeur de la grille
     */
    private void nouvelleGrille(int h, int l) {
        try {
            hauteur = h;
            largeur = l;

            //On arrête le thread de calcul si il a été lancé
            if (threadCalcul.isAlive()) {
                stopThreadCalcul();
            }

            // On recréé l'environnement
            myEnv = new Environnement(hauteur, largeur);
            // et on recréé la grille
            creationGrille();
            etatSauvegarde = true;
            setLocationRelativeTo(this.getParent());
        } catch (OutOfMemoryError e) {
            System.out.println("Grille trop grande. Pas assez de place");
        } catch (Error e) {
            System.out.println("Erreur lors de la création de la grille");
        }
    }

    /**
     * Créé une nouvelle grille à partir d'une version simplifié de l'environnement
     * @param versionSimple Un tableau de booleéns dont les case contiennent true pour une cellule vivante ou false pour une cellule morte
     */
    private void nouvelleGrille(boolean[][] versionSimple) {
        try {
            //On arrête le thread de calcul si il a été lancé
            if (threadCalcul.isAlive()) {
                stopThreadCalcul();
            }
            // On recréé l'environnement
            myEnv = new Environnement(versionSimple);

            hauteur = myEnv.getHauteur();
            largeur = myEnv.getLargeur();


            // et on recréé la grille
            creationGrille();
            etatSauvegarde = true;

            setLocationRelativeTo(this.getParent());
        } catch (OutOfMemoryError e) {
            System.out.println("Grille trop grande. Pas assez de place");
        } catch (Error e) {
            System.out.println("Erreur lors de la création de la grille");
        }
    }

    /**
     * Arrête le thread de calcul
     */
    private void stopThreadCalcul() {
        threadCalcul.interrupt();
        monBoutonStart.setText("Start");
    }

    /**
     * Démarre le thread de calcul 
     */
    private void startThreadCalcul() {
        threadCalcul = new Thread(new Runnable() {

            public void run() {
                boolean ok = true;
                while (ok) {
                    myEnv.nouvelleGenerationParcours();
                    try {
                        Thread.sleep(slideVitesse.getValue());
                    } catch (InterruptedException ex) {
                        ok = false;
                    }
                }
            }
        });
        threadCalcul.start();
        monBoutonStart.setText("Stop");
        etatSauvegarde = false;
    }

    /**
     * Définit l'état de sauvegarde
     * @param etatSauvegarde le nouvel état de sauvegarde
     */
    public void setEtatSauvegarde(boolean etatSauvegarde) {
        this.etatSauvegarde = etatSauvegarde;
    }

    /**
     * Affiche une fenêtre de choix des couleurs pour la couleur correspondant aux cellules mortes
     */
    private void changeCouleurMort() {
        Color choixMort = JColorChooser.showDialog(this, "Choix de la couleur des cellules mortes.", Case.getCouleurMort());
        if (choixMort != null) {
            Case.setCouleurMort(choixMort);
            couleurMort.setBackground(choixMort);
            for (Case[] cases : mesCases) {
                for (Case case1 : cases) {
                    case1.update(null, null);
                }
            }
        }


    }

    /**
     * Affiche une fenêtre de choix des couleurs pour la couleur correspondant aux cellules vivante
     */
    private void changeCouleurVie() {
        Color choixVie = JColorChooser.showDialog(this, "Choix de la couleur des cellules Vies.", Case.getCouleurVie());
        if (choixVie != null) {
            Case.setCouleurVie(choixVie);
            couleurVie.setBackground(choixVie);
            for (Case[] cases : mesCases) {
                for (Case case1 : cases) {
                    case1.update(null, null);
                }
            }
        }
    }

    private void changeZoom(int zoom) {
        int tailleCase = zoom;
        Dimension dimensionCase = new Dimension(tailleCase, tailleCase);
        Dimension dimensionGrille = new Dimension(largeur * tailleCase, hauteur * tailleCase);
        maGrille.setSize(dimensionGrille);
        maGrille.setMaximumSize(dimensionGrille);
        maGrille.setMinimumSize(dimensionGrille);

        for (int i = 0; i < hauteur; i++) {
            for (int j = 0; j < largeur; j++) {
                Case uneCase = mesCases[i][j];
                uneCase.setPreferredSize(dimensionCase);
                uneCase.setMinimumSize(dimensionCase);
                uneCase.setMaximumSize(dimensionCase);
            }
        }
        maGrille.setAlignmentX(CENTER_ALIGNMENT);
        maGrille.setAlignmentY(CENTER_ALIGNMENT);


        /****
         * Initialisation Conteneur de grille
         */
        Dimension dimensionConteneur = new Dimension(300, 300);

        //Si la grille est plus petite que le conteneur il faut réduire le conteneur
        dimensionConteneur.height = dimensionConteneur.height < dimensionGrille.height ? dimensionConteneur.height : dimensionGrille.height;
        dimensionConteneur.width = dimensionConteneur.width < dimensionGrille.width ? dimensionConteneur.width : dimensionGrille.width;

        dimensionConteneur.width += 4; //le +4 permet d'éviter d'avoir des scrollbars lorsque cela n'est pas nécessaire
        dimensionConteneur.height += 4;
        monConteneur.setPreferredSize(dimensionConteneur);
        monConteneur.setMinimumSize(dimensionConteneur);

        Dimension dimensionMax = dimensionGrille;
        dimensionMax.width += 4; //le +4 permet d'éviter d'avoir des scrollbars lorsque cela n'est pas nécessaire
        dimensionMax.height += 4;
        monConteneur.setMaximumSize(dimensionMax);


        int extendedState = (this.getExtendedState());
        Dimension tempSize = this.getSize();
        this.setMinimumSize(null); // pour éviter que la fenetre soit bloquée dans une taille trop grande
        this.setVisible(false);
        this.pack();
        this.repaint();
        this.setMinimumSize(this.getSize());
        this.setLocationRelativeTo(this.getParent());
        this.setExtendedState(extendedState);
        if (extendedState == JFrame.NORMAL) {
            this.setSize(tempSize);
        }
        this.setVisible(true);


    }
}
